package com.cal.utms.entity;

import java.io.Serializable;

import javax.persistence.*;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import com.cal.utms.logAudit.AuditLogInt;
import com.cal.utms.util.ValueConvert;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * The persistent class for the deal database table.
 * 
 */
@Entity
@Table(name = "deal")
@NamedQuery(name = "Deal.findAll", query = "SELECT d FROM Deal d")
public class Deal implements Serializable, AuditLogInt {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(unique = true, nullable = false)
	private int id;

	@Column(name = "ACTUAL_RATE", precision = 10, scale = 4)
	private BigDecimal actualRate;

	@Column(name = "BANK_ACCOUNT", length = 45)
	private String bankAccount;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "CONFIRMED_DATE")
	private Date confirmedDate;

	@Column(name = "CONFIRMED_USER", length = 45)
	private String confirmedUser;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "CREATED_DATE")
	private Date createdDate;

	@Column(name = "CREATED_USER", length = 45)
	private String createdUser;

	@Column(name = "DAY_BASIS", length = 45)
	private String dayBasis;

	@Column(name = "DEAL_CODE", length = 45)
	private String dealCode;

	@Column(name = "DEAL_VALUE", precision = 10, scale = 4)
	private BigDecimal dealValue;

	@Column(name = "MATURITY_VALUE", precision = 10, scale = 4)
	private BigDecimal maturityValue;

	private Integer icp;

	@Temporal(TemporalType.DATE)
	@Column(name = "MATURITY_DATE")
	private Date maturityDate;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "MODIFIED_DATE")
	private Date modifiedDate;

	@Column(name = "MODIFIED_USER", length = 45)
	private String modifiedUser;

	@Column(length = 60)
	private String name;

	@Column(name = "PLACEMENT_FEE", precision = 10, scale = 4)
	private BigDecimal placementFee;

	@Column(name = "PREV_DEAL_PORTION", precision = 10, scale = 4)
	private BigDecimal prevDealPortion;

	@Column(name = "ROLLOVER_SHORTMATURITY", length = 100)
	private String rolloverShortmaturity;

	@Column(name = "SECONDARY_MARKET")
	private Byte secondaryMarket;

	@Column(name = "SELLER_NAME", length = 80)
	private String sellerName;

	@Column(name = "WITHHOLDING_TAX", length = 20)
	private String withholdingTax;

	@Column(name = "WITHHOLDING_TAX_RATE", precision = 10, scale = 4)
	private BigDecimal withholdingTaxRate;

	@Column(name = "WITHHOLDING_CERTIFICATE", length = 20)
	private String withholdingCertificate;

	@Column(length = 12)
	private String status;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "STATUS_CHANGE_DATE")
	private Date statusChangeDate;

	@Temporal(TemporalType.DATE)
	@Column(name = "VALUE_DATE")
	private Date valueDate;

	// uni-directional many-to-one association to Deal
	@ManyToOne
	@JoinColumn(name = "OLD_DEAL_ID")
	private Deal deal;

	// uni-directional many-to-one association to DealType
	@ManyToOne
	@JoinColumn(name = "TYPE_ID")
	private DealType dealType;

	// uni-directional many-to-one association to Fund
	@ManyToOne
	@JoinColumn(name = "FUND_ID")
	private Fund fund;

	// uni-directional many-to-one association to Issure
	@ManyToOne
	@JoinColumn(name = "ISSUER_ID")
	private Issuer issuer;

	// bi-directional many-to-one association to DealInstrumentMap
	@OneToMany(mappedBy = "deal", fetch = FetchType.EAGER)
	@Fetch(value = FetchMode.SUBSELECT)
	private List<DealInstrumentMap> dealInstrumentMaps;

	@ManyToOne
	@JoinColumn(name = "SETTLEMENT_CODE")
	private SettlementMethod settlementMethod;

	@ManyToOne
	@JoinColumn(name = "DELEVARY_METHODE")
	private DelevaryMethod delevarymethode;

	@ManyToOne
	@JoinColumn(name = "DEALER_CODE")
	private Dealer dealerCode;

	public Deal() {
	}

	public int getId() {
		return this.id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public BigDecimal getActualRate() {
		return this.actualRate;
	}

	public void setActualRate(BigDecimal actualRate) {
		this.actualRate = actualRate;
	}

	public String getBankAccount() {
		return this.bankAccount;
	}

	public void setBankAccount(String bankAccount) {
		this.bankAccount = bankAccount;
	}

	public Date getConfirmedDate() {
		return this.confirmedDate;
	}

	public void setConfirmedDate(Date confirmedDate) {
		this.confirmedDate = confirmedDate;
	}

	public String getConfirmedUser() {
		return this.confirmedUser;
	}

	public void setConfirmedUser(String confirmedUser) {
		this.confirmedUser = confirmedUser;
	}

	public Date getCreatedDate() {
		return this.createdDate;
	}

	public void setCreatedDate(Date createdDate) {
		this.createdDate = createdDate;
	}

	public String getCreatedUser() {
		return this.createdUser;
	}

	public void setCreatedUser(String createdUser) {
		this.createdUser = createdUser;
	}

	public String getDayBasis() {
		return this.dayBasis;
	}

	public void setDayBasis(String dayBasis) {
		this.dayBasis = dayBasis;
	}

	public String getDealCode() {
		return this.dealCode;
	}

	public void setDealCode(String dealCode) {
		this.dealCode = dealCode;
	}

	public BigDecimal getDealValue() {
		return this.dealValue;
	}

	public void setDealValue(BigDecimal dealValue) {
		this.dealValue = dealValue;
	}

	public BigDecimal getMaturityValue() {
		return maturityValue;
	}

	public void setMaturityValue(BigDecimal maturityValue) {
		this.maturityValue = maturityValue;
	}

	public Integer getIcp() {
		return this.icp;
	}

	public void setIcp(Integer icp) {
		this.icp = icp;
	}

	public Date getMaturityDate() {
		return this.maturityDate;
	}

	public void setMaturityDate(Date maturityDate) {
		this.maturityDate = maturityDate;
	}

	public Date getModifiedDate() {
		return this.modifiedDate;
	}

	public void setModifiedDate(Date modifiedDate) {
		this.modifiedDate = modifiedDate;
	}

	public String getModifiedUser() {
		return this.modifiedUser;
	}

	public void setModifiedUser(String modifiedUser) {
		this.modifiedUser = modifiedUser;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public BigDecimal getPlacementFee() {
		return this.placementFee;
	}

	public void setPlacementFee(BigDecimal placementFee) {
		this.placementFee = placementFee;
	}

	public BigDecimal getPrevDealPortion() {
		return this.prevDealPortion;
	}

	public void setPrevDealPortion(BigDecimal prevDealPortion) {
		this.prevDealPortion = prevDealPortion;
	}

	public String getRolloverShortmaturity() {
		return this.rolloverShortmaturity;
	}

	public void setRolloverShortmaturity(String rolloverShortmaturity) {
		this.rolloverShortmaturity = rolloverShortmaturity;
	}

	public Byte getSecondaryMarket() {
		return this.secondaryMarket;
	}

	public void setSecondaryMarket(Byte secondaryMarket) {
		this.secondaryMarket = secondaryMarket;
	}

	public String getSellerName() {
		return this.sellerName;
	}

	public void setSellerName(String sellerName) {
		this.sellerName = sellerName;
	}

	public String getStatus() {
		return this.status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public Date getStatusChangeDate() {
		return this.statusChangeDate;
	}

	public void setStatusChangeDate(Date statusChangeDate) {
		this.statusChangeDate = statusChangeDate;
	}

	public Date getValueDate() {
		return this.valueDate;
	}

	public void setValueDate(Date valueDate) {
		this.valueDate = valueDate;
	}

	public Deal getDeal() {
		return this.deal;
	}

	public void setDeal(Deal deal) {
		this.deal = deal;
	}

	public DealType getDealType() {
		return this.dealType;
	}

	public void setDealType(DealType dealType) {
		this.dealType = dealType;
	}

	public Fund getFund() {
		return this.fund;
	}

	public void setFund(Fund fund) {
		this.fund = fund;
	}

	public Issuer getIssuer() {
		return this.issuer;
	}

	public void setIssuer(Issuer issure) {
		this.issuer = issure;
	}

	public List<DealInstrumentMap> getDealInstrumentMaps() {
		return this.dealInstrumentMaps;
	}

	public void setDealInstrumentMaps(List<DealInstrumentMap> dealInstrumentMaps) {
		this.dealInstrumentMaps = dealInstrumentMaps;
	}

	public DealInstrumentMap addDealInstrumentMap(DealInstrumentMap dealInstrumentMap) {
		getDealInstrumentMaps().add(dealInstrumentMap);
		dealInstrumentMap.setDeal(this);

		return dealInstrumentMap;
	}

	public DealInstrumentMap removeDealInstrumentMap(DealInstrumentMap dealInstrumentMap) {
		getDealInstrumentMaps().remove(dealInstrumentMap);
		dealInstrumentMap.setDeal(null);

		return dealInstrumentMap;
	}

	public String getWithholdingTax() {
		return withholdingTax;
	}

	public void setWithholdingTax(String withholdingTax) {
		this.withholdingTax = withholdingTax;
	}

	public BigDecimal getWithholdingTaxRate() {
		return withholdingTaxRate;
	}

	public void setWithholdingTaxRate(BigDecimal withholdingTaxRate) {
		this.withholdingTaxRate = withholdingTaxRate;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public String getWithholdingCertificate() {
		return withholdingCertificate;
	}

	public void setWithholdingCertificate(String withholdingCertificate) {
		this.withholdingCertificate = withholdingCertificate;
	}

	public SettlementMethod getSettlementMethod() {
		return settlementMethod;
	}

	public void setSettlementMethod(SettlementMethod settlementMethod) {
		this.settlementMethod = settlementMethod;
	}

	public DelevaryMethod getDelevarymethode() {
		return delevarymethode;
	}

	public void setDelevarymethode(DelevaryMethod delevarymethode) {
		this.delevarymethode = delevarymethode;
	}

	public Dealer getDealerCode() {
		return dealerCode;
	}

	public void setDealerCode(Dealer dealerCode) {
		this.dealerCode = dealerCode;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Deal) {
			Deal deal = (Deal) obj;
			if (this.actualRate != null && this.actualRate.doubleValue() != deal.actualRate.doubleValue()) {
				System.out.println("actualRate:" + this.actualRate + ":" + deal.actualRate);
				return false;
			}

			if (this.bankAccount != null && !this.bankAccount.equals(deal.bankAccount)) {
				System.out.println("bankAccount:" + this.bankAccount + ":" + deal.bankAccount);
				return false;
			}

			if (this.dayBasis != null && !this.dayBasis.equals(deal.dayBasis)) {
				System.out.println("dayBasis:" + this.dayBasis + ":" + deal.dayBasis);
				return false;
			}

			if (!this.dealCode.equals(deal.dealCode)) {
				System.out.println("dealCode:" + this.dealCode + ":" + deal.dealCode);
				return false;
			}

			if (!this.dealType.getCode().equals(deal.dealType.getCode())) {
				System.out.println("dealType:" + this.dealType + ":" + deal.dealType);
				return false;
			}

			if (this.dealValue.doubleValue() != deal.dealValue.doubleValue()) {
				System.out.println("dealValue:" + this.dealValue + ":" + deal.dealValue);
				return false;
			}

			if (!this.fund.getFundCode().equals(deal.fund.getFundCode())) {
				System.out.println("fundCode:" + this.fund.getFundCode() + ":" + deal.fund.getFundCode());
				return false;
			}
			if (deal.settlementMethod != null) {
				if (!this.settlementMethod.getCode().equals(deal.settlementMethod.getCode())) {
					System.out.println("Settlement Code:" + this.settlementMethod.getCode() + ":" + deal.settlementMethod.getCode());
					return false;
				}
			}
			if (deal.dealerCode != null) {
				if (!this.dealerCode.getCode().equals(deal.dealerCode.getCode())) {
					System.out.println("Dealer Code:" + this.dealerCode.getCode() + ":" + deal.dealerCode.getCode());
					return false;
				}
			}

			if (deal.delevarymethode != null) {
				if (!this.delevarymethode.getCode().equals(deal.delevarymethode.getCode())) {
					System.out.println("Delevary Code:" + this.delevarymethode.getCode() + ":" + deal.delevarymethode.getCode());
					return false;
				}
			}

			if (this.icp != null && (!this.icp.equals(deal.icp))) {
				System.out.println("icp:" + this.icp + ":" + deal.icp);
				return false;
			}

			if (!this.issuer.getCode().equals(deal.issuer.getCode())) {
				System.out.println("issuerCode:" + this.issuer.getCode() + ":" + deal.issuer.getCode());
				return false;
			}

			if (this.maturityDate != null && !this.maturityDate.equals(deal.maturityDate)) {
				System.out.println("maturityDate:" + this.maturityDate + ":" + deal.maturityDate);
				return false;
			}

			if (this.name != null && !this.name.equals(deal.name)) {
				System.out.println("name:" + this.name + ":" + deal.name);
				return false;
			}

			if (this.placementFee != null && (this.placementFee.doubleValue() != deal.placementFee.doubleValue())) {
				System.out.println("placementFee:" + this.placementFee + ":" + deal.placementFee);
				return false;
			}

			if (this.secondaryMarket != null && !(this.secondaryMarket.equals(deal.secondaryMarket))) {
				System.out.println("secondaryMarket:" + this.secondaryMarket + ":" + deal.secondaryMarket);
				return false;
			}

			if (this.sellerName != null && !this.sellerName.equals(deal.sellerName)) {
				System.out.println("sellerName:" + this.sellerName + ":" + deal.sellerName);
				return false;
			}

			if (this.valueDate != null && !this.valueDate.equals(deal.valueDate)) {
				System.out.println("valueDate:" + this.valueDate + ":" + deal.valueDate);
				return false;
			}

			if (this.withholdingTax != null && !this.withholdingTax.equals(deal.withholdingTax)) {
				System.out.println("withholdingTax:" + this.withholdingTax + ":" + deal.withholdingTax);
				return false;
			}

			if (this.withholdingTaxRate != null && this.withholdingTaxRate.doubleValue() != deal.withholdingTaxRate.doubleValue()) {
				System.out.println("withholdingTaxRate:" + this.withholdingTaxRate + ":" + deal.withholdingTaxRate);
				return false;
			}

			return true;

		} else {
			return false;
		}
	}

	public static Deal createClone(Deal deal) {
		Deal newDeal = new Deal();
		newDeal.setActualRate(deal.getActualRate());
		newDeal.setBankAccount(deal.getBankAccount());
		newDeal.setConfirmedDate(deal.getConfirmedDate());
		newDeal.setConfirmedUser(deal.getConfirmedUser());
		newDeal.setCreatedDate(deal.getCreatedDate());
		newDeal.setCreatedUser(deal.getCreatedUser());
		newDeal.setDayBasis(deal.getDayBasis());
		newDeal.setDealCode(deal.getDealCode());
		newDeal.setDealValue(deal.getDealValue());
		newDeal.setMaturityValue(deal.getMaturityValue());
		newDeal.setIcp(deal.getIcp());
		newDeal.setMaturityDate(deal.getMaturityDate());
		newDeal.setModifiedDate(deal.getModifiedDate());
		newDeal.setModifiedUser(deal.getModifiedUser());
		newDeal.setName(deal.getName());
		newDeal.setPlacementFee(deal.getPlacementFee());
		newDeal.setPrevDealPortion(deal.getPrevDealPortion());
		newDeal.setRolloverShortmaturity(deal.getRolloverShortmaturity());
		newDeal.setSecondaryMarket(deal.getSecondaryMarket());
		newDeal.setSellerName(deal.getSellerName());
		newDeal.setWithholdingTax(deal.getWithholdingTax());
		newDeal.setWithholdingTaxRate(deal.getWithholdingTaxRate());
		newDeal.setWithholdingCertificate(deal.getWithholdingCertificate());
		newDeal.setStatus(deal.getStatus());
		newDeal.setStatusChangeDate(deal.getStatusChangeDate());
		newDeal.setValueDate(deal.getValueDate());
		newDeal.setDealType(deal.getDealType());
		newDeal.setFund(deal.getFund());
		newDeal.setIssuer(deal.getIssuer());
		// id
		// oldDeal
		// dealInstrumentMaps
		return newDeal;
	}

	@Transient
	@Override
	public Long getLogId() {
		return ValueConvert.toLong(this.id);
	}

	@Transient
	@Override
	public String getLogDeatil() {
		StringBuilder sb = new StringBuilder();
		sb.append("Deal Id : ").append(id).append("Deal code : ").append(this.dealCode);
		return sb.toString();
	}

}